package com.xueqiu.movieplaymanagersystem.controller.admin;

import com.github.pagehelper.PageInfo;
import com.xueqiu.movieplaymanagersystem.model.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.xueqiu.movieplaymanagersystem.entity.*;
import com.xueqiu.movieplaymanagersystem.service.BlogService;
import com.xueqiu.movieplaymanagersystem.service.UserService;
import com.xueqiu.movieplaymanagersystem.service.PublicService;
import com.xueqiu.movieplaymanagersystem.utils.StringUtils;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xueqiu
 */
@Controller
@RequestMapping("/admin")
public class BlogController {
    private PublicService<Type> typesService;
    private PublicService<Tag> tagService;
    @Autowired
    private BlogService blogService;
    @Autowired
    private UserService userService;

    @Autowired
    public void setTypesService(
            @Qualifier("typesService")
            PublicService<Type> typesService
    ) {
        this.typesService = typesService;
    }

    @Autowired
    public void setTagService(
            @Qualifier("tagService")
            PublicService<Tag> tagService
    ) {
        this.tagService = tagService;
    }

    /**
     * 跳转控制器；跳转到新闻管理页面
     *
     * @param model 模型参数
     * @return 新闻管理页面
     */
    @GetMapping({"/blogList", "/blogList.html"})
    public String blogList(Model model) {
        //查询结果可能为empty
        List<Type> types = typesService.findByKeyWord(null, -1, -1).getList();
        model.addAttribute("types", types);
        return "admin/blog/blogList";
    }

    /**
     * 根据标题关键字和类型id和是否推荐状态查询新闻
     *
     * @param title     标题关键字
     * @param typeId    类型id
     * @param isCommend 是否推荐
     * @param page      当前页
     * @param limit     每页限制条数
     * @return 可能为empty
     */
    @GetMapping("/tableBlog")
    @ResponseBody
    public JsonResult<Blog> tableBlog(
            @RequestParam(name = "title", required = false)
            String title,
            @RequestParam(name = "typeId", required = false)
            String typeId,
            @RequestParam(name = "isCommend", required = false, defaultValue = "false")
            boolean isCommend,
            int page,
            int limit
    ) {
        JsonResult<Blog> jsonResult = new JsonResult<>();
        //标题关键字是否为空
        if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(title)) {
            title = null;
        }
        //类别id是否为空
        if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(typeId)) {
            typeId = null;
        }
        PageInfo<Blog> resultPageInfo = blogService.findByKeyWordAndTypeIdAndCommend(title, typeId, isCommend, page, limit);

        jsonResult.Success(
                "条件查询成功！",
                resultPageInfo.getList(),
                (int) resultPageInfo.getTotal()
                );
        return jsonResult;
    }

    /**
     * 删除新闻；根据新闻id
     * @param id 新闻id
     * @return 删除成功与否
     */
    @GetMapping("/deleteBlog/{id}")
    @ResponseBody
    public JsonResult<String> deleteBlog(
            @PathVariable(name = "id")
            String id
    ) {
        JsonResult<String> jsonResult = new JsonResult<>();
        if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(id)) {
            jsonResult.Error("id参数不合法");
            return jsonResult;
        }

        boolean isDelete = blogService.removeById(id);

        if (!isDelete) {
            jsonResult.Error("删除失败！");
            return jsonResult;
        }

        jsonResult.Success("删除成功！");
        return jsonResult;
    }

    /**
     * 批量删除新闻；根据新闻名称列表
     * @param blogs 新闻名称列表
     * @return 删除成功与否
     */
    @PostMapping("/deleteBlogs")
    @ResponseBody
    public JsonResult<String> deleteBlogs(
            @RequestParam(name = "blogs[]")
            String[] blogs
    ) {
        JsonResult<String> jsonResult = new JsonResult<>();
        if (blogs.length == 0) {
            jsonResult.Error("名称列表参数不合法；不存在名称列表参数");
            return jsonResult;
        }

        for (String blog : blogs) {
            if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(blog)) {
                jsonResult.Error("单个名称元素不合法！");
                return jsonResult;
            }
        }

        List<String> list = Arrays.asList(blogs);
        int delete = blogService.removeByIdBatch(list);

        if (delete == 0) {
            jsonResult.Error("批量删除失败！");
            return jsonResult;
        }
        if (delete == blogs.length) {
            jsonResult.Success("批量删除成功！");
            return jsonResult;
        }

        jsonResult.setCode(3);
        jsonResult.setMsg("部分数据未删除！");
        return jsonResult;
    }

    /**
     * 前置跳转控制器；跳转到编写新闻页面
     * @param model 模型参数
     * @return 编写新闻页面
     */
    @GetMapping({"/writeBlog.html", "/writeBlog"})
    public String writeBlog(Model model) {
        List<Type> types = typesService.findByKeyWord(null, -1, -1).getList();
        model.addAttribute("types", types);
        List<Tag> tags = tagService.findByKeyWord(null, -1, -1).getList();
        model.addAttribute("tags", tags);
        return "admin/blog/writeBlog";
    }

    /**
     * 发布新闻
     * @param blog 数据源
     * @param bindingResult 绑定工具
     * @param tagIds 标签ID列表
     * @param session 域
     * @return 发布成功与否
     */
    @PostMapping("/blog/publish")
    @ResponseBody
    public JsonResult<String> publish(
            @Validated
            Blog blog,
            BindingResult bindingResult,
            @RequestParam(name = "tagIds[]")
            String[] tagIds,
            HttpSession session
    ) {
        return publishOrSave(blog, bindingResult, tagIds, "发布失败！", "publish", session);
    }

    /**
     * 保存新闻
     * @param blog 数据源
     * @param bindingResult 绑定工具
     * @param tagIds 标签ID列表
     * @param session 域
     * @return 保存成功与否
     */
    @PostMapping("/blog/save")
    @ResponseBody
    public JsonResult<String> save(
            @Validated
            Blog blog,
            BindingResult bindingResult,
            @RequestParam(name = "tagIds[]")
            String[] tagIds,
            HttpSession session
    ) {
        return publishOrSave(blog, bindingResult, tagIds, "保存失败！", "save", session);
    }

    /**
     * 发布或者保存的主要实现代码
     * @param blog 数据源
     * @param bindingResult 绑定工具
     * @param tagIds 标签ID列表
     * @param message 操作失败的提示
     * @param method 执行的方式；发布还是保存
     * @param session 域
     * @return 成功与否
     */
    private JsonResult<String> publishOrSave(
            @Validated
            Blog blog,
            BindingResult bindingResult,
            @RequestParam(name = "tagIds[]")
            String[] tagIds,
            String message,
            String method,
            HttpSession session
    ) {
        JsonResult<String> jsonResult = hasError(bindingResult);
        if (jsonResult != null) {
            return jsonResult;
        }

        jsonResult = new JsonResult<>();
        if (tagIds != null && tagIds.length > 0) {
            List<String> tagList = Arrays.asList(tagIds);
            //这一步转成HashSet是为了去除重复的元素
            Set<String> tagSet = new HashSet<>(tagList);
            if (tagList.size() != tagSet.size()) {
                //元素数量不一致，所以存在重复元素
                tagList = new ArrayList<>(tagSet);
            }
            blog.setTagId(tagList);
        }

        User user = (User) session.getAttribute("user");
        if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(blog.getAuthor())) {
            blog.setAuthor(user.getNickName());
        }

        boolean success;
        if ("save".equals(method)) {
            success = blogService.save(blog);
        } else {
            success = blogService.publish(blog);
        }
        if (!success) {
            jsonResult.Error(message);
            return jsonResult;
        }

        jsonResult.Success(message.substring(0,2) + "成功");
        return jsonResult;
    }


    /**
     * 判断绑定工具是否鉴别出错误
     * @param bindingResult 绑定工具
     * @return 有错则返回收集的错误信息；无错则返回null
     */
    private JsonResult<String> hasError(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            JsonResult<String> jsonResult = new JsonResult<>();
            List<ObjectError> errors = bindingResult.getAllErrors();
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("[");
            for (int i = 0; i < errors.size(); i++) {
                String defaultMessage = errors.get(i).getDefaultMessage();
                stringBuilder.append(defaultMessage);
                if (i != errors.size() - 1) {
                    stringBuilder.append(",");
                }
            }
            stringBuilder.append("]");
            String errorMsg = stringBuilder.toString();
            if (errorMsg.length() == 2) {
                //代表errorMsg其实就是"[]"，是空的；代表上述收集错误消息的过程出现了错误
                errorMsg = "[收集错误消息过程出现错误]";
            }
            jsonResult.Error(errorMsg);
            return jsonResult;
        }
        //没有错误则返回null
        return null;
    }

    /**
     * 前置跳转控制器；跳转到编辑新闻页面
     * @param id 新闻id
     * @param model 模型参数
     * @return 编辑新闻页面
     */
    @GetMapping("/blog/editBlog/{id}")
    public String editBlog(
            @PathVariable(name = "id")
            String id,
            Model model
    ) {
        if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(id)) {
            return "error/404";
        }

        Blog blog = blogService.findById(id);

        List<String> tagIds = blog.getTags().stream()
                .map(Tag::getId)
                .collect(Collectors.toList());
        /*List<String> tagIds = new ArrayList<>();
        for (Tag tag : tagList) {
            tagIds.add(tag.getId());
        }*/
        model.addAttribute("tagIds", tagIds);
        model.addAttribute("blog", blog);

        List<Type> types = typesService.findByKeyWord(null, -1, -1).getList();

        model.addAttribute("types", types);

        List<Tag> tags = tagService.findByKeyWord(null, -1, -1).getList();

        model.addAttribute("tags", tags);
        return "admin/blog/editBlog";
    }

    /**
     * 前置跳转控制器；跳转到新闻预览页面
     * @param id 新闻id
     * @param model 模型参数
     * @return 新闻预览页面
     */
    @GetMapping("/blog/preBlog/{id}")
    public String preBlog(
            @PathVariable(name = "id")
            String id,
            Model model
    ) {
        if (StringUtils.isNullOrEmptyOrOnlyWhiteSpace(id)) {
            return "error/404";
        }

        Blog blog = blogService.findContentById(id);

        if (blog == null) {
            return "error/404";
        }

        model.addAttribute("blog", blog);
        return "admin/blog/preBlog";
    }

    /**
     * 抛弃此方法
     * @param session 域
     */
    /*@GetMapping("/blog/keepAlive")
    public void keepAlive(HttpSession session) {
        Object user = session.getAttribute("user");
        if (user == null) {
            User userInfo = userService.findIndexUserInfo();
            session.setAttribute("user", userInfo);
        }
    }*/
}
